﻿package velbus.modules 
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.SharedObject;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	import mx.controls.TextArea;
	import mx.utils.StringUtil;
	import SWFKit.Folder;
	import SWFKit.Shell;
	import velbus.modules.data.Playlist;
	
	/**
	* ...
	* @author Gert Stalpaert (gert@stogo.net)
	*/
	public class PlaylistModule 
	{
		
		///array of Playlist classes

		static public var playlists:Array;
		static public var isPlaying:Boolean;
		static public var currentPlayListIndex:int = 0; 
		static public var currentPlayList:Playlist;
		static public var nowPlaying:String = "";

		static private var _status:XML;
		static private var _settings:XML;
		static private var _msg:TextArea;
		static private var _lastPlayListName:String = "";
		static private var _lastNowPlaying:String = "";
		static private var _lastIsPlaying:Boolean;
		static private var _so:SharedObject;
		static private var _statusTimer:Timer;
		static private var _iidLcd:Number;
		
		
		
		public function PlaylistModule(settings:XML, msg:TextArea):void 
		{
			
			_settings = settings;
			_msg = msg; 
			playlists = new Array();
			
			try {
				var playlistFolder:Folder = new Folder(_settings.playlist.folder);
				if (!playlistFolder) {
					_msg.text += "Warning: Error reading PlaylistFolder: " + _settings.playlist.folder + "\n"
				}
				var folderArray:Array = playlistFolder.files();
				playlistFolder.Release();
			
				//add empty playlist at pos 0;
				var empty:Playlist = new Playlist(_settings.playlist.empty);
				playlists.push(empty);
				
				for (var i:int = 0; i < folderArray.length; i++) 
				{
					if (String(folderArray[i]).substr( -3, 3) == _settings.playlist.extension && folderArray[i] != _settings.playlist.empty) {
						//_msg.text += "playlist found: " + folderArray[i] + "\n"
						playlists.push(new Playlist(folderArray[i]));
					}
					
				}
				if (playlists.length == 0) {
					_msg.text += "No playlist files found with extension " + _settings.playlist.extension + "\n";
				} else {
					_msg.text += "playlists found: " + playlists.length + "\n"
				}
				//_msg.text += "pl:" + playlists + "\n"
			
				_so = SharedObject.getLocal("VelbusSocket");
				
				if (!_so.data.noAudio) {
					_so.data.noAudio = true;
				}
				
				if (_so.data.currentPlayListIndex){
					currentPlayListIndex = Math.min(playlists.length, _so.data.currentPlayListIndex);
				} else {
					currentPlayListIndex = 0;
				}
								
				currentPlayList = Playlist(playlists[currentPlayListIndex]);
				msg.text += "currentPlayList:" + currentPlayList + "\n" ;
				
				_statusTimer = new Timer(5000);
				_statusTimer.addEventListener(TimerEvent.TIMER, onStatusTimer);
				_statusTimer.start();
				
			} catch (e:Error) {
				msg.text += "Warning: Playlist folder can not be scanned from a browser window, only from exe.\n" ;
			}
			
		}
		
		private function onStatusTimer(e:TimerEvent):void 
		{
			var ul:URLLoader = new URLLoader(new URLRequest(_settings.playlist.statusInfo));
			ul.removeEventListener(Event.COMPLETE, onStatusXmlLoaded);
			ul.addEventListener(Event.COMPLETE, onStatusXmlLoaded);
			ul.removeEventListener(IOErrorEvent.IO_ERROR, onStatusXmlError);
			ul.addEventListener(IOErrorEvent.IO_ERROR, onStatusXmlError);
			
			//setLcdLine(_address, 3, "^|StuBru      |+");
			//setLcdLine(_address, 4, "|Geen muziek(|-");
		}
		
		private function onStatusXmlError(e:IOErrorEvent):void 
		{
			_msg.text += "Error loading playlist status info at " + _settings.playlist.statusInfo + "\n";
		}
		
		private function onStatusXmlLoaded(e:Event):void 
		{
			_status = new XML();
			_status = XML(e.target.data);
			
			isPlaying = (_status.@playing == "1");
			if (isPlaying) {
				nowPlaying  = _status.song.artist + "-" + _status.song.title;
			} else {
				nowPlaying  = "Not playing";
			}
			//_msg.text += "is playing:" + isPlaying + " - nowPlaying: " + nowPlaying + "\n";
			//_msg.text += "nowPlaying: " + nowPlaying.substr(0,16) + " - _lastNowPlaying: " + _lastNowPlaying.substr(0,16) + "\n";
			
			updateDisplays(undefined);
			
		}
		
		static public function nextPlaylist(addressSender:int): void 
		{
			if (_so.data.noAudio) {
				_so.data.noAudio = false;
				currentPlayListIndex = _so.data.currentPlayListIndex;
			} else {
				currentPlayListIndex++;
			}
			if (currentPlayListIndex > playlists.length-1) {
				currentPlayListIndex  = 1; //0 is the empty one
			}
			
			_so.data.currentPlayListIndex = currentPlayListIndex;
			
			startPlayList(currentPlayListIndex,addressSender);
		}
		
		static public function startPlayList(playListIndex:int, addressSender:int):void
		{
			try {
				
				currentPlayList = Playlist(playlists[playListIndex]);
				
				_msg.text += "Start playlist " + currentPlayList.name + "\n";
								
				var shell:Shell = new Shell();	
				_statusTimer.stop();
				_statusTimer.start();
				updateDisplays(addressSender);
				shell.run("\"" + _settings.playlist.mediaPlayer + "\"" + "\"" + currentPlayList.fn + "\"" , 1);
			} catch (e:Error) {
				_msg.text += "Warning: Unable to run playlists online\n";
			}
		}
		
		static public function loadEmptyPlaylist(addressSender:int):void {
			_so.data.currentPlayListIndex = currentPlayListIndex;
			_so.data.noAudio = true;
			currentPlayListIndex = 0; //the first one is the empty one by design
			startPlayList(currentPlayListIndex,addressSender); 
		}
		
		
		static public function updateDisplays(addressSender:int): void 
		{
			//_msg.text += "Update playlist displays: " + currentPlayList.name + "\n";
			var lcdLine:String;
			var displays:XMLList; 
			
			if (currentPlayList && currentPlayList.name != _lastPlayListName){
				_lastPlayListName = currentPlayList.name;
				lcdLine = currentPlayList.name;
				
				displays = _settings.playlist.displays.playlistNameInfo;
				//_msg.text += "displays::" + displays + "\n";
				sendMessageToDisplays(lcdLine, displays, addressSender);
			}
			
			
			if (nowPlaying.substr(0,16) != _lastNowPlaying.substr(0,16)){
				_lastNowPlaying = nowPlaying;
				lcdLine = nowPlaying;
				displays = _settings.playlist.displays.nowPlayingInfo;
				sendMessageToDisplays(lcdLine, displays, addressSender);
			}
			
		}
		
		static private function sendMessageToDisplays(lcdLine:String, displays:XMLList, addressSender:int):void
		{
				
			while (lcdLine.length < 16) {
				lcdLine += " ";
			}
			
			_msg.text += "lcd: " + lcdLine + "\n";
			
			var lcd:XML;
			for each(lcd in displays) {
				var text:String = "";
				var mask:String = lcd.@lcdMask;
				var lcdIndex:int = 0;
				for (var j:int = 0; j < mask.length; j++) 
				{
					text += (mask.charAt(j) == "@") ? lcdLine.charAt(lcdIndex++) : mask.charAt(j);
				}
				//_msg.text += "lcd::" + parseInt(lcd.@address, 16) + "- " + parseInt(lcd.@lcdLineNr) + "\n";
				_msg.text += addressSender + "<>" + parseInt(lcd.@address, 16) + ":" + text + "\n";
				//if (addressSender == parseInt(lcd.@address, 16)) {
					PushButtonAndTimer.setLcdLine(parseInt(lcd.@address, 16), parseInt(lcd.@lcdLineNr), text);
				/*} else {
					flash.utils.clearInterval(_iidLcd);
					_iidLcd = flash.utils.setTimeout(PushButtonAndTimer.setLcdLine, 15000, parseInt(lcd.@address, 16), parseInt(lcd.@lcdLineNr), text);
				}*/
			}
		}
		
	}
	
}